08 模块与包
一个文件写了几百行代码?该拆成模块了。多个模块有关系?该组织成包了。Python的模块系统让你把代码拆成多个文件,用import按需导入。
一、模块基础
1.1 什么是模块
一个.py文件就是一个模块。模块可以定义函数、类和变量。
python
# mymodule.py
def greet(name):
return f"Hello, {name}!"
PI = 3.141591.2 导入模块
python
>>> import mymodule
>>> mymodule.greet("World")
'Hello, World!'
>>> mymodule.PI
3.141591.3 from...import
python
>>> from mymodule import greet, PI
>>> greet("World")
'Hello, World!'
>>> PI
3.141591.4 导入所有名称
python
>>> from mymodule import *不推荐,会导入模块里所有不以_开头的名称,容易造成命名冲突。模块可以用__all__列表控制import *导入哪些名称:
python
# mymodule.py
__all__ = ['greet', 'PI']二、模块搜索路径
2.1 搜索顺序
导入模块时,Python按以下顺序查找:
- 当前目录
PYTHONPATH环境变量指定的目录- 标准库目录
- 第三方包目录(
site-packages)
2.2 sys.path
python
>>> import sys
>>> sys.path
['', '/usr/lib/python3.14', '/usr/lib/python3.14/lib-dynload', ...]sys.path是一个列表,可以修改它来添加自定义搜索路径。
三、__name__变量
3.1 模块名
每个模块都有__name__属性:
python
# mymodule.py
print(__name__) # 输出: mymodule3.2 main
当模块被直接运行时,__name__等于'__main__':
python
# mymodule.py
def main():
print("模块被直接运行")
if __name__ == '__main__':
main()当被import导入时,if块不会执行。这是Python惯用的模块入口模式。
四、dir()函数
4.1 查看模块内容
python
>>> import mymodule
>>> dir(mymodule)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'greet', 'PI']4.2 查看当前命名空间
python
>>> dir()
['__builtins__', '__name__', ...]
>>> import mymodule
>>> dir()
['__builtins__', '__name__', 'mymodule']五、包
5.1 包的结构
包是包含__init__.py文件的目录:
mypackage/
__init__.py
module1.py
module2.py
subpackage/
__init__.py
module3.py__init__.py可以是空文件,也可以包含初始化代码。
5.2 导入包
python
import mypackage.module1
mypackage.module1.some_function()
from mypackage import module1
module1.some_function()
from mypackage.module1 import some_function
some_function()5.3 init.py的作用
__init__.py在包被导入时执行,可以控制包的接口:
python
# mypackage/__init__.py
from .module1 import some_function
from .module2 import another_function这样就可以直接从包导入:
python
from mypackage import some_function六、相对导入
6.1 点号语法
在包内部,可以用相对导入:
python
# mypackage/module1.py
from . import module2 # 导入同包的module2
from .module2 import func # 从module2导入func
from .. import top_module # 导入上级包的模块
from ..other_package import mod # 导入兄弟包的模块一个点.表示当前包,两个点..表示上级包。
6.2 注意事项
相对导入只能在包内使用,不能在顶层脚本中使用。如果模块被直接运行(__name__ == '__main__'),相对导入会失败。
七、标准库路径
7.1 常见位置
python
>>> import sys
>>> print(sys.prefix) # Python安装目录
>>> print(sys.exec_prefix) # 扩展模块目录7.2 site-packages
第三方包安装在这里:
python
>>> import site
>>> site.getsitepackages()
['/usr/lib/python3.14/site-packages', ...]八、包管理工具
8.1 pip
bash
# 安装包
pip install requests
# 指定版本
pip install requests==2.31.0
# 升级
pip install --upgrade requests
# 卸载
pip uninstall requests
# 查看已安装
pip list
# 导出依赖
pip freeze > requirements.txt
# 从文件安装
pip install -r requirements.txt8.2 requirements.txt
requests==2.31.0
flask>=2.0
pandas~=2.0版本约束:==精确匹配、>=大于等于、~=兼容版本。
九、虚拟环境
9.1 创建虚拟环境
bash
# 创建
python -m venv myenv
# 激活(Linux/macOS)
source myenv/bin/activate
# 激活(Windows)
myenv\Scripts\activate
# 退出
deactivate9.2 为什么用虚拟环境
不同项目可能依赖不同版本的库。虚拟环境让每个项目有独立的依赖环境,互不干扰。
十、总结
| 概念 | 说明 |
|---|---|
| 模块 | 一个.py文件 |
| 包 | 包含__init__.py的目录 |
import | 导入模块 |
from...import | 从模块导入特定名称 |
__name__ | 模块名,直接运行时为'__main__' |
dir() | 查看模块或命名空间的内容 |
| 相对导入 | .当前包,..上级包 |
pip | 包管理工具 |
| 虚拟环境 | 独立的依赖环境 |
if __name__ == '__main__'是模块入口的标准写法。虚拟环境是项目开发的标配,避免全局安装包。